﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Grundy.Common;

namespace Grundy.Message
{
    
    [CollectionDataContract]
    public class IdentifierCollection : ICollection<Identifier>
    {
        public override string ToString()
        {
            return string.Join(", ", (_identifiers ?? new List<Identifier>()).Select(i => i.ToString()));
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (IdentifierCollection)) return false;
            var other = (IdentifierCollection) obj;
            return new CollectionComparer<Identifier>().Equals(this, other);
        }

        public override int GetHashCode()
        {
            return (_identifiers != null ? _identifiers.GetHashCode() : 0);
        }

        public static bool operator ==(IdentifierCollection left, IdentifierCollection right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(IdentifierCollection left, IdentifierCollection right)
        {
            return !Equals(left, right);
        }

        private List<Identifier> _identifiers;

        public IdentifierCollection()
        {
            _identifiers = new List<Identifier>();
        }

        public IdentifierCollection(IEnumerable<Identifier> identifiers)
        {
            _identifiers = (identifiers ?? new List<Identifier>())
                           .Where(i => i != null)
                           .Select(i => i.Copy())
                           .ToList();
        }


        public IEnumerator<Identifier> GetEnumerator()
        {
            return _identifiers.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return _identifiers.GetEnumerator();
        }

        public void Add(Identifier item)
        {
            _identifiers.Add(item);
        }

        public void Clear()
        {
            _identifiers.Clear();
        }

        public bool Contains(Identifier item)
        {
            return _identifiers.Contains(item);
        }

        public void CopyTo(Identifier[] array, int arrayIndex)
        {
            _identifiers.CopyTo(array, arrayIndex);
        }

        public bool Remove(Identifier item)
        {
            return _identifiers.Remove(item);
        }

        public int Count
        {
            get { return _identifiers.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public IEnumerable<Identifier> this[string key]
        {
            get
            {
                return _identifiers.Where(i => i.Name.EqualsIgnoreCase(key)).ToList();
            }
        }

        public bool IsAdequateToIdentifyClient()
        {
            var identifierTypes = _identifiers.Select(i => i.GetType())
                                  .Distinct().ToList();
            return (identifierTypes.Contains(typeof(ProcessorIdentifier)) && identifierTypes.Contains(typeof(BiosIdentifier)) && identifierTypes.Contains(typeof(MacAddressIdentifier)))
                   || (identifierTypes.Contains(typeof(UserNameIdentifier)) && identifierTypes.Contains(typeof(UserSidIdentifier)));
        }
    }
}